package com.effectiv.crm.service.impl;

import java.lang.reflect.Field;
import java.util.List;

import javax.inject.Inject;
import javax.inject.Named;

import jodd.bean.BeanUtil;
import jodd.util.ReflectUtil;
import jodd.util.StringUtil;

import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;

import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import static org.springframework.data.mongodb.core.query.Criteria.where;  
import static org.springframework.data.mongodb.core.query.Query.query;  
 
import lombok.extern.slf4j.Slf4j;

import com.effectiv.crm.domain.Lead;
import com.effectiv.crm.repository.LeadRepository;
import com.effectiv.crm.service.api.LeadService;

@Slf4j
@Named
public class LeadServiceImpl implements LeadService {
	
	
	@Inject
	private LeadRepository repository;
	
	@Inject
	private MongoTemplate template;
	
	private String ignoreFields [] = {"serialVersionUID","id","version","createdDate","lastModifiedDate","createdBy","lastModifiedBy"};

	public void save(Lead lead) {
		log.debug("Lead is being saved - {}",lead);
		repository.save(lead);
		
	}

	public void update(Lead lead) {
		//TODO - Cache reflected fields
		Field fields [] = ReflectUtil.getAccessibleFields(Lead.class);
		
		String fieldName = null;
		
		Update u = new Update();
		
		for(Field f : fields){
			fieldName = f.getName();
			if(StringUtil.equalsOne(fieldName,ignoreFields) == -1){
				u.set(fieldName, BeanUtil.getPropertySilently(lead, fieldName));
			}
		}
		
		template.updateFirst(query(where("id").is(lead.getId()) ), u, Lead.class);
				
	}

	public List<Lead> findAll() {
		return repository.findAll();
	}

	public Lead findOne(String id) {
		return repository.findOne(id);
	}

	public void delete(Lead lead) {
		Update u = new Update();
		u.set("deleted", true);
		template.updateFirst(query(where("id").is(lead.getId()) ), u, Lead.class);
	}

	@Override
	public List<Lead> findLastN(int noOfDocuments) {
		Query query = new Query();
		query.limit(noOfDocuments);
		query.with(new Sort(Sort.Direction.DESC, "createdDate"));
		
		return template.find(query, Lead.class);
		
	}

	@Override
	public List<Lead> findByDeleted(boolean deleted) {
		
		return repository.findByDeleted(deleted);
	}

}
